#pragma once

#include "drift.h"
#include <QMessageBox>
namespace qbe::editing::Drift {

void updateVisualRender(ecs::EventWriter<Drift::Event> event_writer) {
  event_writer.send({Code::OpUpdate});
}
void clearVisualRender(ecs::EventWriter<Drift::Event> event_writer) {
  event_writer.send({Code::OpExit});
}

void clearModeData(ecs::Query query) {
  auto& param = query.get_resource<DriftModel>();
  param.update = false;
  param.m_can_create = false;
  param.entity_hover = entt::null;
  param.get_ui_data = false;
  param.is_first_ui = true;
  param.first_open = false;
  param.inited = false;
  param.clear();
  auto event_writer = query.get_event_writer<Drift::Event>();
  clearVisualRender(event_writer);
}

void exit(ecs::Query query) {
  clearModeData(query);
  auto& state = query.get_resource<state::State>();
  state.switchMode(state::EditingModeType::None);
}

void exit_callback(ecs::Query query, state::AllModeType mode) {
  clearModeData(query);
}

std::vector<entt::entity> getSelectedObjs(entt::registry& reg) {
  std::vector<entt::entity> selected_objs;
  auto view = reg.view<select::SelectTag>();

  view.each([&selected_objs](entt::entity entity) {
    // 标记被移动的对象
    selected_objs.push_back(entity);
  });

  return selected_objs;
}

bool IsSupportDriftObj(entt::registry& reg, entt::entity entt) {
  auto select_line = reg.try_get<qlib::Path::s_ptr>(entt);
  auto select_polygon = reg.try_get<qlib::Polygon::s_ptr>(entt);
  auto select_rectangle = reg.try_get<qlib::Rectangle::s_ptr>(entt);
  auto select_ellipse = reg.try_get<qlib::Ellipse::s_ptr>(entt);
  if (select_line) {
    double line_width = 0;
    return (*select_line)->getLineWidth() == 0;
  } else if (select_ellipse) {
    // 正圆才能偏移
    double elli_radius_x = (*select_ellipse)->radius.x;
    double elli_radius_y = (*select_ellipse)->radius.y;
    return std::abs(elli_radius_x - elli_radius_y) < 10e-3;
  } else if (select_polygon || select_rectangle) {
    return true;
  } else {
    return false;
  }
}

void init(entt::registry& reg, ecs::Commands commands, ecs::Query query) {
  auto& state = query.get_resource<state::State>();
  state.addExitCall(state::EditingModeType::Drift, exit_callback);
}

//偏移
void update(entt::registry& ecs_reg, ecs::Query query, ecs::Bus& bus) {
  auto& state = query.get_resource<state::State>();
  // 仅在模式执行
  if (state.getEditingMode() != state::EditingModeType::Drift)
    return;

  uint32_t layer;
  if (!state.getCurrentLayer(layer)) {
    QMessageBox::information(nullptr, QObject::tr("error"), QObject::tr("No layer selected, unable to drift"));
    exit(query);
  }

  auto& cmd = query.get_resource<layout::CellCmd>();
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();
  auto cell = cmd.get_cell();
  auto& reg = cell->reg;
  auto& cell_state = query.get_resource<layout::CellState>();
  auto& axis_t = query.get_resource<axis::Axis>();
  auto& param = query.get_resource<DriftModel>();
  param.grpc_interface = query.get_resource<tools::GrpcInterfaceObjcet>();
  param.layer = layer;
  auto& hand = query.get_resource<vsg::ref_ptr<input::HandleBundle>>();
  auto event_writer = query.get_event_writer<Drift::Event>();
  auto& select_event_writer = query.get_event_writer<select::Event>();
  auto& undoRedoModule = query.get_resource<undoRedoT::UndoRedoModule>();
  auto& select_cmd = query.get_resource<select::SelectCmd>();
  select::SelectModel& selectModel = query.get_resource<select::SelectModel>();
  select::OverallModel& overallSelect = query.get_resource<select::OverallModel>();
  select::SelectPartModel& partSelect = query.get_resource<select::SelectPartModel>();
  if (param.get_ui_data && !param.inited) {
    //清除所有高亮
    param.grpc_interface.initOffSet();
    param.inited = true;
    select_cmd.clear_select();
    select_cmd.clear_select_parts();
    select_cmd.clear_hover();
    select_cmd.clear_hover_parts();
  }
  if (!param.update) {
    //独立的选择系统
    if (hand->mouse_move) {
      param.entity_hover = entt::null;
      // 鼠标查询范围
      auto r = 30 / axis_t.scale;
      r = r > 30 ? 30 : r;
      select_cmd.set_mouse_range(r);
      auto& x = axis_t.real_x;
      auto& y = axis_t.real_y;
      select_cmd.query_nodes(x, y);
      std::multimap<double, entt::entity> order_borders;
      select_cmd.get_select(x, y, order_borders);
      if (order_borders.size() > 0) {
        auto it_begin = order_borders.begin();
        param.entity_hover = it_begin->second;
      }
      select_cmd.clear_hover();
      if (param.entity_hover != entt::null)
        select_cmd.add_hovers(std::vector<entt::entity>{param.entity_hover});
    }

    if (hand->mousePressed(vsg::ButtonMask::BUTTON_MASK_1)) {
      if (param.entity_hover != entt::null)
        select_cmd.add_selects({param.entity_hover});
    }
  }

  auto selecc_arr = getSelectedObjs(reg);
  bool only_select_one = selecc_arr.size() == 1;  //只选中一个对象
  if (only_select_one) {
    //对象是否支持偏移
    if (!IsSupportDriftObj(reg, selecc_arr[0])) {
      //清除高亮
      only_select_one = false;
      //清除选中状态
      for (auto [e] : reg.view<select::SelectTag>().each()) {
        reg.remove<select::SelectTag>(e);
      }
      select_event_writer.send(select::Event{select::Code::SelectCancel});
    }
  }
  auto ui_cancle = bus.receive<qbe::UiMessage::Drift_Cancle>();
  //第一次打开并取消参数面板
  if (param.is_first_ui && !ui_cancle.empty()) {
    exit(query);
  }
  auto res = bus.receive<qbe::UiMessage::DriftUi_Ok>();

  if (!res.empty()) {
    param.m_drift_distance = res[0].m_drift_distance;
    param.get_ui_data = true;
    bus.send(qbe::UiMessage::DriftUi_Close());  //关闭面板
    param.grpc_interface.initOffSet();
    //清除选中状态
    if (overallSelect.hover_entity != entt::null) {
      overallSelect.hover_entity = entt::null;
      for (auto [e] : reg.view<select::HoverTag>().each()) {
        reg.remove<select::HoverTag>(e);
      }
      for (auto [e] : reg.view<select::SelectTag>().each()) {
        reg.remove<select::SelectTag>(e);
      }
      select_event_writer.send(select::Event{select::Code::HoverCancel});
      select_event_writer.send(select::Event{select::Code::SelectCancel});
    }
    param.is_first_ui = false;
    param.first_open = true;
  }

  if (param.is_first_ui && !param.first_open) {
    // 等待ui消息
    return;
  }

  //交互逻辑
  bool begin = false;
  bool update = false;
  bool cancel = false;
  bool complete = false;

  if (hand->keyReleased(vsg::KEY_Escape)) {
    cancel = true;  // 按下esc时，退出
  } else if (only_select_one) {
    if (hand->mousePressed(vsg::ButtonMask::BUTTON_MASK_1))
      complete = true;
    else if (hand->mouse_move) {
      update = true;
      param.update = true;
    }
  } else if (hand->mouse_move) {
  }
  // std::string sendOperaterMessageInfo = "mode: drift | Left click to confirm the placement position";

  if (update) {
    //清除预选中状态
    if (overallSelect.hover_entity != entt::null) {
      overallSelect.hover_entity = entt::null;
      for (auto [e] : reg.view<select::HoverTag>().each()) {
        reg.remove<select::HoverTag>(e);
      }
      select_event_writer.send(select::Event{select::Code::HoverCancel});
    }

    double x = axis_t.real_x;
    double y = axis_t.real_y;
    auto select_line = reg.try_get<qlib::Path::s_ptr>(selecc_arr[0]);
    auto select_polygon = reg.try_get<qlib::Polygon::s_ptr>(selecc_arr[0]);
    auto select_rectangle = reg.try_get<qlib::Rectangle::s_ptr>(selecc_arr[0]);
    auto select_ellipse = reg.try_get<qlib::Ellipse::s_ptr>(selecc_arr[0]);
    param.m_can_create = true;
    if (select_line) {
      driftLineFunc(param, *select_line, x, y);
    } else if (select_polygon) {
      driftPolygonFunc(param, *select_polygon, x, y);
    } else if (select_rectangle) {
      // driftPolygonFunc(param, (*select_rectangle)->to_polygon(), x, y);
      driftRectangle(param, *select_rectangle, x, y);
    } else if (select_ellipse && abs((*select_ellipse)->radius.x - (*select_ellipse)->radius.y) < 10e-3) {
      // 正圆才能偏移
      // driftPolygonFunc(param, (*select_ellipse)->to_polygon(), x, y);
      driftCircle(param, *select_ellipse, x, y);
    } else {
      // unsupportDriftObj();
      // 不支持偏移的对象处理
      // LayoutCtrlData::deleteRenderElement(copy_ele);
      // LayoutCtrlData::cancelHighlight(); //  取消高亮
      // copy_ele = nullptr;
      // selected = nullptr;
      param.m_can_create = false;
      param.m_line_eles.clear();
      param.m_polygon_eles.clear();
      // sendOperaterMessageInfo = "mode: drift element | select the object to offset";
    }
  }

  //执行偏移
  if (complete) {
    // if (copy_ele == nullptr) {
    //   return;
    // }

    if (false == param.m_can_create) {
      // LayoutCtrlData::deleteRenderElement(copy_ele);
      // for (auto i : m_line_eles) {
      //   if (i) {
      //     LayoutCtrlData::deleteRenderElement(i);
      //   }
      // }
      // for (auto i : m_polygon_eles) {
      //   if (i) {
      //     LayoutCtrlData::deleteRenderElement(i);
      //   }
      // }
      // return;
    }
    // std::shared_ptr<QedaKernel::Cell> currentCell;
    // currentCell = LayoutCtrlData::getCurrentCell();

    // LayoutCtrlData::drawStarUndoRedo();

    // std::vector<EelementNode*> copy_ele_vec;
    // if (copy_ele->getEleType() == ElememtType::LINE) {
    //   for (auto i : param.m_line_eles) {
    //     if (i) {
    //       copy_ele_vec.push_back(i);
    //       LayoutCtrlData::deleteRenderElement(i);
    //     }
    //   }
    // } else if (copy_ele->getEleType() == ElememtType::POLYGON) {
    //   for (auto i : param.m_polygon_eles) {
    //     if (i) {
    //       copy_ele_vec.push_back(i);
    //       LayoutCtrlData::deleteRenderElement(i);
    //     }
    //   }
    //   for (auto i : m_line_eles) {
    //     if (i) {
    //       copy_ele_vec.push_back(i);
    //       LayoutCtrlData::deleteRenderElement(i);
    //     }
    //   }
    // } else {
    //   copy_ele_vec.push_back(copy_ele);
    //   LayoutCtrlData::deleteRenderElement(copy_ele);
    // }

    // auto copy_copy_vec = copyElement(copy_ele_vec);
    // LayoutCtrlData::drawStarUndoRedo();
    // for (int i = 0; i < copy_copy_vec.size(); ++i) {
    //   QEDA_Internals::getInstance()->addPolygon(currentCell, copy_copy_vec[i]->m_graph);
    //   LayoutCtrlData::updateQuadTreeNode(copy_copy_vec[i]);
    // }
    // LayoutCtrlData::drawEndUndoRedo();
    // LayoutCtrlData::cancelHighlight();
    // LayoutCtrlData::updateView();
    // LayoutCtrlData::closePickAngleAdsorpForwardPoint();
    // LayoutCtrlData::sendOperaterMessageInfo(tr("mode: drift element | select the object to offset"));

    //修改数据 偏移了线 多边形 矩形 圆
    if (!param.m_line_eles.empty() || !param.m_polygon_eles.empty() || !param.m_rectangle_eles.empty() || !param.m_ellipse_eles.empty()) {
      undoRedoModule.start(cell);
      for (auto path : param.m_line_eles) {
        entt::entity entity = reg.create();
        reg.emplace<qlib::Path::s_ptr>(entity, path);  // 绑定指针到实体
        layout_cmd.add(entity);
        undoRedoModule.add(entity);
      }
      for (auto polygon : param.m_polygon_eles) {
        entt::entity entity = reg.create();
        reg.emplace<qlib::Polygon::s_ptr>(entity, polygon);  // 绑定指针到实体
        layout_cmd.add(entity);
        undoRedoModule.add(entity);
      }
      for (auto rectangle : param.m_rectangle_eles) {
        entt::entity entity = reg.create();
        reg.emplace<qlib::Rectangle::s_ptr>(entity, rectangle);  // 绑定指针到实体
        layout_cmd.add(entity);
        undoRedoModule.add(entity);
      }
      for (auto ellipse : param.m_ellipse_eles) {
        entt::entity entity = reg.create();
        reg.emplace<qlib::Ellipse::s_ptr>(entity, ellipse);  // 绑定指针到实体
        layout_cmd.add(entity);
        undoRedoModule.add(entity);
      }
      // undoRedoModule.dele(selecc_arr[0]);
      // layout_cmd.remove(selecc_arr[0]);
      undoRedoModule.end();

      //取消选中
      select_cmd.clear_select();
      select_cmd.clear_hover();
    }
    param.grpc_interface.initOffSet();
    param.update = false;
  }

  if (cancel || complete) {
    //退出模式
    param.m_line_eles.clear();
    param.m_polygon_eles.clear();
    param.m_rectangle_eles.clear();
    param.m_ellipse_eles.clear();
    param.m_can_create = false;
    if (cancel) {
      exit(query);
      // return;
    }
  }

  QString sendOperaterMessageInfo;
  if (param.inited) {
    if (param.m_can_create) {
      sendOperaterMessageInfo = QObject::tr("mode: drift | Left click to confirm the placement position");
    } else if (param.is_too_large) {
      sendOperaterMessageInfo = QObject::tr("mode: drift element | drift distance is too large");
    } else {
      sendOperaterMessageInfo = QObject::tr("mode: drift element | select the object to offset");
    }
  }
  if (cancel) {
    sendOperaterMessageInfo = "";
  }
  bus.send<qbe::UiMessage::OperatorInfoMessage>(qbe::UiMessage::OperatorInfoMessage{sendOperaterMessageInfo});
  param.updateVisualData();
  updateVisualRender(event_writer);  //更新可视化
}

void post(entt::registry& reg, ecs::Commands commands, ecs::Query query, ecs::Bus& bus) {}

void clear_event(ecs::Query query) {
  query.get_resource<ecs::Event<Event>>().clear();
}

void DriftPlugin::build(ecs::App& app) {
  app.init_resource<DriftModel>(DriftModel{});
  app.init_event<Event>();
  app.add_systems<ecs::stage::Startup>(init);
  app.add_systems<ecs::stage::Update>(update);
  app.add_systems<ecs::stage::PostUpdate>(post);
  app.add_systems<ecs::stage::Last>(clear_event);
};
}  // namespace qbe::editing::Drift